package com.leyou.search.service;


import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.search.clients.BrandClient;
import com.leyou.search.clients.CategoryClient;
import com.leyou.search.clients.GoodsClient;
import com.leyou.search.clients.SpecificationClient;
import com.leyou.search.pojo.Goods;
import com.leyou.search.repository.GoodsRepository;
import com.leyou.utils.JsonUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class IndexService {

    @Autowired
    private CategoryClient categoryClient;

    @Autowired
    private BrandClient brandClient;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private SpecificationClient specificationClient;

    @Autowired
    private GoodsRepository goodsRepository;

    private static final Logger logger = LoggerFactory.getLogger(IndexService.class);

    /**
     * 将spuBo转化成goods,补充goods中新属性的值
     *
     * @param spu
     * @return
     */
    public Goods buildGoods(SpuBo spu) {
        Goods goods = new Goods();

        BeanUtils.copyProperties(spu, goods);
        //除此以外,还有四个属性  all price skus specs

        // all: 所有需要被搜索的信息，包含标题，分类，甚至品牌
        String all = spu.getTitle();

        List<String> names = this.categoryClient.queryNameByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

        String brandName = this.brandClient.queryNameById(spu.getBrandId());

        all = brandName + " " + all + StringUtils.join(names, " ");

        goods.setAll(all);


        //通过spu_id查skus
        List<Sku> skus = this.goodsClient.querySkuBySpuId(spu.getId());

        List<Long> priceList = new ArrayList<>();

        List<Map<String, Object>> skuList = new ArrayList<>();

        skus.forEach(sku -> {
            priceList.add(sku.getPrice());

            Map<String, Object> skuMap = new HashMap<>();
            skuMap.put("id", sku.getId());
            skuMap.put("title", sku.getTitle());
            skuMap.put("image", sku.getImages());
            skuMap.put("price", sku.getPrice());

            skuList.add(skuMap);
        });

        goods.setPrice(priceList);

        //按价格升序排序
        Collections.sort(skuList, Comparator.comparing(o -> ((Long) o.get("price"))));

        goods.setSkus(JsonUtils.serialize(skuList));

        //specs: 可搜索的规格参数，key是参数名，值是参数值

        //spuDetail的内容
        SpuDetail spuDetail = this.goodsClient.querySpuDetailById(spu.getId());

        //通用规格参数值
        String genericSpec = spuDetail.getGenericSpec();

        Map<Long, String> genericSpecMap = JsonUtils.parseMap(genericSpec, Long.class, String.class);

        //特有规格参数值
        String specialSpec = spuDetail.getSpecialSpec();

        Map<Long, List<String>> specialSpecMap = JsonUtils.nativeRead(specialSpec, new TypeReference<Map<Long, List<String>>>() {
        });


        //查询分类对应的可搜索的规格参数
        List<SpecParam> specParams = this.specificationClient.querySpecParam(null, spu.getCid3(), null, true);

        //处理规格参数显示问题,默认显示id+值,处理后显示id对应的名称+值
        Map<String, Object> specs = new HashMap<>();

        specParams.forEach(specParam -> {

            String name = specParam.getName();
            Long paramId = specParam.getId();

            Object value = null;
            if (specParam.getGeneric()) {//为true是通用属性,false为特有属性
                value = genericSpecMap.get(paramId);
                if (specParam.getNumeric()) {
                    value = this.chooseSegment(value.toString(), specParam);
                }
            } else {//特有参数
                value = specialSpecMap.get(paramId);
            }
            if (null == value) {//如果没有值就显示其它
                value = "其它";
            }
            specs.put(name, value);
        });

        goods.setSpecs(specs);

        return goods;
    }


    private String chooseSegment(String value, SpecParam p) {
        double val = NumberUtils.toDouble(value);
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = NumberUtils.toDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = NumberUtils.toDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }


    public void createIndex(Long id) {
        Spu spu = this.goodsClient.querySpuById(id);
        SpuBo spuBo = new SpuBo();
        BeanUtils.copyProperties(spu, spuBo);
        Goods goods = this.buildGoods(spuBo);
        this.goodsRepository.save(goods);
    }

    public void deleteIndex(Long id) {

    }
}
